﻿#include "chatroom.h"
#include "ui_chatroom.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include "personitem.h"
#include <memory>

struct onlineuser
{
    QString account;
    QByteArray photo;
};

struct User
{
    User(const QString& account, QListWidgetItem *item, QListWidget *w)
    {
        this->account = account;
        this->item = item;
        this->w = w;
    }

    ~User()
    {
        delete item;
        delete  w;
    }

    QString account; // 账号
    QListWidgetItem *item; // 左边在线列表项
    QListWidget *w; // 右边聊天框
};

ChatRoom::ChatRoom(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ChatRoom)
{
    ui->setupUi(this);

    ui->pushButton_chat->setIcon(QPixmap(":/img/chat.png"));
    ui->pushButton_chat->setIconSize(ui->pushButton_chat->size());
    ui->pushButton_chat->setStyleSheet("background-color: rgb(70,70,70);");

    ui->pushButton_music->setIcon(QPixmap(":/img/music.png"));
    ui->pushButton_music->setIconSize(ui->pushButton_music->size());
    ui->pushButton_music->setStyleSheet("background-color: rgb(70,70,70);");

    ui->pushButton_cloud->setIcon(QPixmap(":/img/cloud.png"));
    ui->pushButton_cloud->setIconSize(ui->pushButton_cloud->size());
    ui->pushButton_cloud->setStyleSheet("background-color: rgb(70,70,70);");
}

ChatRoom::~ChatRoom()
{
    delete ui;
}

void ChatRoom::WriteToServer(const QJsonObject &obj)
{
    // 将QJsonObject包装成一个QJsonDocument对象,并将QJsonDocument转换为JSON格式的QByteArray
    auto data = QJsonDocument(obj).toJson();
    int size =  data.size(); // 获取数据(data)的长度
    socket->write((char*)&size,sizeof(int)); // 将数据长度写入套接字(告诉接收方数据多长)
    socket->write(data); // 将Json数据写入套接字
}

void ChatRoom::process(const QByteArray &data)
{
    auto obj = QJsonDocument::fromJson(data).object(); // 解析Json数据，允许访问Json数据中的各个字段
//    qDebug() << "chatroom.cpp处理json逻辑:" << QJsonDocument(obj).toJson() << endl;
    ui->listWidget->clear(); // 清空当前的在线列表
    QJsonArray accountListArray = obj["accountlist"].toArray(); // 提取出"accountlist"字段

    QList<onlineuser> onlinelist;
    for (const auto& item : accountListArray)
    {
        if (item.isObject())
        {
            QJsonObject userObj = item.toObject();
            onlineuser user;
            if (userObj.contains("account") && userObj["account"].isString())
            {
                user.account = userObj["account"].toString();
            }
            if (userObj.contains("photo") && userObj["photo"].isString())
            {
                QString photoBase64 = userObj["photo"].toString();
                user.photo = QByteArray::fromBase64(photoBase64.toUtf8());
            }
            onlinelist.append(user);
        }
    }

    for(auto ite = onlinelist.begin(); ite != onlinelist.end(); ite++) // 遍历
    {
       QListWidgetItem * item = new QListWidgetItem; // 创建新的列表项，QListWidgetItem是QListWidget中的基本单元，表示单个条目
       item->setSizeHint(QSize(ui->listWidget->width(),100)); // 设置列表项的高度和宽度
       PersonItem *w = new PersonItem; // 创建个性化小部件
       w->setFixedSize(item->sizeHint()); // 设置小部件的大小与列表项匹配
       w->SetPost(ite->photo); // 设置头像
       w->SetName(ite->account); // 设置名称
       ui->listWidget->addItem(item); // 将新创建的列表项添加到ui->listWidget_online中
       ui->listWidget->setItemWidget(item,w); // 将小部件w设置到由item表示的列表项上，在listWidget_online 中，item所对应的列表项将不再显示默认的文本或图标，而是显示我们自定义的小部件w

       QListWidget *chatW = new QListWidget; // 每个用户创建一个新的聊天窗口
       ui->stackedWidget->addWidget(chatW); // 将窗口放入ui->stackedWidget中
       std::shared_ptr<User> user = std::make_shared<User>(ite->account, item, chatW); // 将用户名、对应的列表项以及聊天窗口封装起来
       users.push_back(user); // 将其添加到全局的users容器中
    }
}

void ChatRoom::GetFromName(const QString &fromName)
{
    name = fromName;
}

void ChatRoom::GetSocket(QTcpSocket *socket)
{
    this->socket = socket; // 接收传递过来的套接字
}

void ChatRoom::closeEvent(QCloseEvent *event)
{
    int ret = QMessageBox::question(this, "确认关闭", "你确定要返回登录界面吗？", QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
    if (ret == QMessageBox::Yes)
    {
        // 接受关闭事件，窗口将被关闭
        event->accept();
        emit ExitChat();
    }
    else
    {
        // 忽略关闭事件，窗口不会关闭
        event->ignore();
    }
}

void ChatRoom::on_pushButton_chat_clicked()
{
    qDebug() << "点击聊天按钮" << endl;
    QJsonObject obj; // 构建Json对象
    obj["request"] = "ONLINELIST"; // 请求类型为ONLINELIST
    obj["fromName"] = name; // 标识发送方名称
    qDebug() << name << endl;
    WriteToServer(obj); // 将Json数据写入套接字
}
